package com.huaxin.hxmodulesystem.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.huaxin.hxjwt.entity.JwtModel;
import com.huaxin.hxjwt.config.JwtUtils;
import com.huaxin.hxmodulesystem.common.PasswordUtil;
import com.huaxin.hxmodulesystem.dto.ResponseCode;
import com.huaxin.hxmodulesystem.dto.ResponseResult;
import com.huaxin.hxmodulesystem.dto.request.*;
import com.huaxin.hxmodulesystem.dto.response.LoginByPhoneAndUserNameAndPasswordRespDTO;
import com.huaxin.hxmodulesystem.dto.response.WxLoginRespDTO;
import com.huaxin.hxmodulesystem.mapper.UserMapper;
import com.huaxin.hxmodulesystem.models.Organization;
import com.huaxin.hxmodulesystem.models.Permission;
import com.huaxin.hxmodulesystem.models.Role;
import com.huaxin.hxmodulesystem.models.User;
import com.huaxin.hxmodulesystem.service.OrganizationService;
import com.huaxin.hxmodulesystem.service.RolePermissionService;
import com.huaxin.hxmodulesystem.service.RoleService;
import com.huaxin.hxmodulesystem.service.UserService;
import com.huaxin.thirdpartyinterface.wechat.WeChatUtils;

import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.annotations.Param;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
@RequiredArgsConstructor
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    private final WeChatUtils weChatUtils;


    private final CacheManager cacheManager;

    private final ObjectMapper objectMapper = new ObjectMapper();

    private final ApplicationContext applicationContext;

    private final OrganizationService organizationService;


    private final RolePermissionService rolePermissionService;

    //微信端登录
    @Override
    public ResponseResult<WxLoginRespDTO> loginOrRegister(WxUserLoginReqDTO in) {
        // 1. 获取 session_key 和 openid
        JSONObject sessionInfo = weChatUtils.getSessionKeyAndOpenId(in.getCode());
        String sessionKey = sessionInfo.getString("session_key");
        String openId = sessionInfo.getString("openid");
        if (StringUtils.isBlank(openId)) {
            return ResponseResult.failure(ResponseCode.INTERNAL_ERROR, "登录异常，请稍后重试！", null);
        }
        WxLoginRespDTO out = new WxLoginRespDTO();
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("openId", openId);
        User users = this.baseMapper.selectOne(queryWrapper);
        if (users == null) {
            User newUsers = new User();
            newUsers.setWechatOpenid(openId);
            newUsers.setStatus(1);
            newUsers.setLoginType(2);
            newUsers.setUserType(1); //默认为普通用户
            // 保存用户昵称和头像（如果提供了 userInfo）
            if (in.getUserInfo() != null) {
                newUsers.setNickname(in.getUserInfo().getNickName());
                newUsers.setAvatarUrl(in.getUserInfo().getAvatarUrl());
            }

            if (this.baseMapper.insert(newUsers) > 0) {
                // 生成 JWT Token
                JwtModel jwtModel = new JwtModel();
                jwtModel.setOpenId(openId);
                jwtModel.setUserId(newUsers.getId());
                jwtModel.setUserType(newUsers.getUserType());
                String token = JwtUtils.generateToken(jwtModel);
                out.setToken(token);
                out.setUserId(newUsers.getId());
                out.setOpenId(openId);
                return ResponseResult.ok(out);
            } else {
                return ResponseResult.failure(ResponseCode.INTERNAL_ERROR, "登录失败，请稍后再试！", null);
            }
        } else {
            if (users.getStatus() != 1) {
                return ResponseResult.failure(ResponseCode.INTERNAL_ERROR, "您的账号已被封禁，无法登录！", null);
            }
            if (in.getUserInfo() != null) {
                users.setNickname(in.getUserInfo().getNickName());
                users.setAvatarUrl(in.getUserInfo().getAvatarUrl());
                this.baseMapper.updateById(users);
            }
            // 生成 JWT Token
            JwtModel jwtModel = new JwtModel();
            jwtModel.setOpenId(openId);
            jwtModel.setUserId(users.getId());
            jwtModel.setUserType(users.getUserType());
            jwtModel.setOrgId(users.getOrgId());
            jwtModel.setFamilyId(users.getFamilyId());
            String token = JwtUtils.generateToken(jwtModel);
            out.setToken(token);
            out.setUserId(users.getId());
            out.setOpenId(openId);
            out.setOrgId(users.getOrgId());
            out.setFamilyId(users.getFamilyId());
            //权限
            if (StringUtils.isNotBlank(users.getRoleId())) {
                List<Permission> permission = rolePermissionService.queryPermissionListByRoleId(users.getRoleId(), users.getUserType(), users.getOrgId());
                if (permission != null && permission.size() > 0) {
                    out.setPermissions(permission);
                }
            }
            return ResponseResult.ok(out);
        }
    }

    //更新用户信息
    @Override
    public ResponseResult<String> updateUserInfo(UpdateUserInfoReqDTO in) {
        if (StringUtils.isBlank(in.getUserId())) {
            return ResponseResult.failure(ResponseCode.INTERNAL_ERROR, "获取不到用户！", null);
        }
        if (in.getUserType() == null || in.getUserType() <= 0) {
            return ResponseResult.failure(ResponseCode.INTERNAL_ERROR, "请选择用户类型！", null);
        }
        String successMessage = "资料更新成功！";
        User users = this.baseMapper.selectById(in.getUserId());
        if (users == null) {
            return ResponseResult.failure(ResponseCode.INTERNAL_ERROR, "用户不存在！", null);
        } else {
            users.setNickname(in.getNickname());
            users.setAvatarUrl(in.getAvatarUrl());
            users.setPhone(in.getPhone());
            users.setUserType(in.getUserType());
            users.setStatus(1);
            users.setArea(in.getArea());
            users.setAddress(in.getAddress());
            users.setLongitude(in.getLongitude());
            users.setLatitude(in.getLatitude());
            users.setIdCardCharacter(in.getIdCardCharacter());
            users.setIdCardNationalEmblem(in.getIdCardNationalEmblem());
            if (users.getUserType() == 1 && !StringUtils.isBlank(in.getOrgCode()) && !StringUtils.isBlank(in.getOrgName())) {
                Organization organization = organizationService.getOrganizationByCode(in.getOrgCode());
                if (organization == null) {
                    AddOrganizationReqDTO addOrganizationReqDTO = new AddOrganizationReqDTO();
                    addOrganizationReqDTO.setName(in.getOrgName());
                    addOrganizationReqDTO.setCode(in.getOrgCode());
                    addOrganizationReqDTO.setAdminTel(in.getOrgAdminTel());
                    addOrganizationReqDTO.setAdminRealName(in.getOrgAdminRealName());
                    addOrganizationReqDTO.setArea(in.getOrgArea());
                    addOrganizationReqDTO.setAddress(in.getOrgAddress());
                    addOrganizationReqDTO.setLongitude(in.getOrgLongitude());
                    addOrganizationReqDTO.setLatitude(in.getOrgLatitude());
                    addOrganizationReqDTO.setIdCardCharacter(in.getOrgIdCardCharacter());
                    addOrganizationReqDTO.setIdCardNationalEmblem(in.getOrgIdCardNationalEmblem());
                    addOrganizationReqDTO.setBusinessLicenseImage(in.getBusinessLicenseImage());
                    Organization newOrg = organizationService.addOrganization(addOrganizationReqDTO);
                    if (organization != null) {
                        users.setOrgId(newOrg.getId());
                    }
                } else {
                    users.setUserType(2);
                    successMessage = "基础资料保存成功，但企业绑定失败，请联系该企业管理员为您绑定账户关系！";
                }
            } else {
                users.setUserType(2);
            }
            if (this.baseMapper.updateById(users) > 0) {
                return ResponseResult.ok(successMessage);
            } else {
                return ResponseResult.failure(ResponseCode.INTERNAL_ERROR, "更新失败，请稍后再试！", null);
            }
        }
    }

    //注册用户
    @Override
    public ResponseResult<String> registerUser(RegisterUserReqDTO in) {
        if (StringUtils.isBlank(in.getPhone())) {
            return ResponseResult.failure(ResponseCode.INTERNAL_ERROR, "请输入手机号！", null);
        }
        if (StringUtils.isBlank(in.getPassword())) {
            return ResponseResult.failure(ResponseCode.INTERNAL_ERROR, "请输入密码！", null);
        }
        if (this.baseMapper.selectCount(new QueryWrapper<User>().eq("phone", in.getPhone())) > 0) {
            return ResponseResult.failure(ResponseCode.INTERNAL_ERROR, "手机号已存在！", null);
        }
        //检查用户名是否存在
        if (this.baseMapper.selectCount(new QueryWrapper<User>().eq("username", in.getUsername())) > 0) {
            return ResponseResult.failure(ResponseCode.INTERNAL_ERROR, "用户名已存在！", null);
        }
        String successMessage = "注册成功！";
        User newUsers = new User();
        newUsers.setUserType(in.getUserType());
        newUsers.setPhone(in.getPhone());
        // 使用 BCrypt 加密密码
        String hashedPassword = PasswordUtil.hashPassword(in.getPassword());
        newUsers.setPassword(hashedPassword);
        newUsers.setUsername(in.getUsername());
        newUsers.setLoginType(in.getUserType());
        newUsers.setStatus(1);
        newUsers.setNickname(in.getNickname());
        newUsers.setAvatarUrl(in.getAvatarUrl());
        newUsers.setArea(in.getArea());
        newUsers.setAddress(in.getAddress());
        newUsers.setLongitude(in.getLongitude());
        newUsers.setLatitude(in.getLatitude());
        newUsers.setIdCardCharacter(in.getIdCardCharacter());
        newUsers.setIdCardNationalEmblem(in.getIdCardNationalEmblem());
        if (newUsers.getUserType() == 2 && !StringUtils.isBlank(in.getOrgCode()) && !StringUtils.isBlank(in.getOrgName()) && in.getIsSync()) {
            Organization organization = organizationService.getOrganizationByCode(in.getOrgCode());
            if (organization == null) {
                AddOrganizationReqDTO addOrganizationReqDTO = new AddOrganizationReqDTO();
                addOrganizationReqDTO.setName(in.getOrgName());
                addOrganizationReqDTO.setCode(in.getOrgCode());
                addOrganizationReqDTO.setAdminTel(in.getOrgAdminTel());
                addOrganizationReqDTO.setAdminRealName(in.getOrgAdminRealName());
                addOrganizationReqDTO.setArea(in.getOrgArea());
                addOrganizationReqDTO.setAddress(in.getOrgAddress());
                addOrganizationReqDTO.setLongitude(in.getOrgLongitude());
                addOrganizationReqDTO.setLatitude(in.getOrgLatitude());
                addOrganizationReqDTO.setIdCardCharacter(in.getOrgIdCardCharacter());
                addOrganizationReqDTO.setIdCardNationalEmblem(in.getOrgIdCardNationalEmblem());
                addOrganizationReqDTO.setBusinessLicenseImage(in.getBusinessLicenseImage());
                Organization newOrg = organizationService.addOrganization(addOrganizationReqDTO);
                if (organization != null) {
                    newUsers.setOrgId(newOrg.getId());
                }
            } else {
                newUsers.setUserType(2);
                successMessage = "账户注册成功，但企业绑定失败，请联系该企业管理员为您绑定账户关系！";
            }
        } else {
            newUsers.setUserType(2);
            newUsers.setOrgId(in.getOrgId());
        }
        if (this.baseMapper.insert(newUsers) > 0) {
            return ResponseResult.ok(successMessage);
        }
        return ResponseResult.failure(ResponseCode.INTERNAL_ERROR, "注册失败，请稍后再试！", null);
    }

    //用户用手机号码加密码进行登录
    @Override
    public ResponseResult<LoginByPhoneAndUserNameAndPasswordRespDTO> loginByPhoneAndUserNameAndPassword(String phone, String userName, String password) {
        if (StringUtils.isBlank(phone) && StringUtils.isBlank(userName)) {
            return ResponseResult.failure(ResponseCode.INTERNAL_ERROR, "请输入手机号或用户名！", null);
        }

        if (StringUtils.isBlank(password)) {
            return ResponseResult.failure(ResponseCode.INTERNAL_ERROR, "请输入密码！", null);
        }

        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        boolean hasPhone = phone != null && !phone.trim().isEmpty();
        boolean hasUsername = userName != null && !userName.trim().isEmpty();
        // 构建 (phone = ? OR username = ?)
        if (hasPhone && hasUsername) {
            wrapper.eq(User::getPhone, phone)
                    .or()
                    .eq(User::getUsername, userName);
        } else if (hasPhone) {
            wrapper.eq(User::getPhone, phone);
        } else if (hasUsername) {
            wrapper.eq(User::getUsername, userName);
        }
        // 添加 AND status = 1
        wrapper.eq(User::getStatus, 1);
        User users = this.baseMapper.selectOne(wrapper);
        if (users == null) {
            return ResponseResult.failure(ResponseCode.INTERNAL_ERROR, "用户不存在！", null);
        } else {
            if (users.getStatus() != 1) {
                return ResponseResult.failure(ResponseCode.INTERNAL_ERROR, "您的账号已被封禁，无法登录！", null);
            }
            if (!PasswordUtil.verifyPassword(password, users.getPassword())) {
                return ResponseResult.failure(ResponseCode.INTERNAL_ERROR, "密码错误！", null);
            }
            // 登录成功，生成 JWT Token
            JwtModel jwtModel = new JwtModel();
            jwtModel.setOpenId(users.getWechatOpenid());
            jwtModel.setUserId(users.getId());
            jwtModel.setUserType(users.getUserType());
            jwtModel.setOrgId(users.getOrgId());
            jwtModel.setFamilyId(users.getFamilyId());
            String token = JwtUtils.generateToken(jwtModel);
            LoginByPhoneAndUserNameAndPasswordRespDTO result = new LoginByPhoneAndUserNameAndPasswordRespDTO();
            result.setToken(token);
            result.setUser(users);
            if (StringUtils.isNotBlank(users.getOrgId())) {
                //组织结构
                Organization organization = organizationService.getById(users.getOrgId());
                if (organization != null) {
                    result.setOrg(organization);
                }
            }
            //权限
            if (StringUtils.isNotBlank(users.getRoleId())) {
                List<Permission> permission = rolePermissionService.queryPermissionListByRoleId(users.getRoleId(), users.getUserType(), users.getOrgId());
                if (permission != null && permission.size() > 0) {
                    result.setPermission(permission);
                }
            }
            return ResponseResult.ok(result);
        }
    }

    //修改密码
    @Override
    public ResponseResult<String> updatePassword(UpdatePasswordReqDTO in) {
        if (in == null) {
            return ResponseResult.parameterError(null, "参数错误");
        }
        if (StringUtils.isBlank(in.getUserId())) {
            return ResponseResult.parameterError(null, "登录失效！");
        }
        if (StringUtils.isBlank(in.getOldPassword())) {
            return ResponseResult.parameterError(null, "旧密码不能为空");
        }
        if (StringUtils.isBlank(in.getNewPassword())) {
            return ResponseResult.parameterError(null, "新密码不能为空");
        }
        User user = this.baseMapper.selectById(in.getUserId());
        if (user == null) {
            return ResponseResult.unauthorized(null, "用户不存在！");
        }
        if (!PasswordUtil.verifyPassword(in.getOldPassword(), user.getPassword())) {
            return ResponseResult.failure(ResponseCode.INTERNAL_ERROR, "旧密码错误！", null);
        }
        user.setPassword(PasswordUtil.hashPassword(in.getNewPassword()));
        if (this.baseMapper.updateById(user) > 0) {
            return ResponseResult.ok("密码修改成功！");
        } else {
            return ResponseResult.failure(ResponseCode.INTERNAL_ERROR, "密码修改失败！", null);
        }
    }

    //找回密码
    @Override
    public ResponseResult<String> findPasswordByPhone(FindPasswordByPhoneReqDTO in) {
        if (StringUtils.isBlank(in.getPhone())) {
            return ResponseResult.parameterError(null, "手机号不能为空！");
        }
        if (StringUtils.isBlank(in.getNewPassword())) {
            return ResponseResult.parameterError(null, "新密码不能为空！");
        }
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("phone", in.getPhone());
        User user = this.baseMapper.selectOne(queryWrapper);
        if (user == null) {
            return ResponseResult.notFound(null, "用户不存在！");
        }
        user.setPassword(PasswordUtil.hashPassword(in.getNewPassword()));
        return this.baseMapper.updateById(user) > 0 ? ResponseResult.ok(null) : ResponseResult.failure(ResponseCode.INTERNAL_ERROR, "修改密码失败！", null);
    }

    //禁用或启用用户；status=1启用，status=0禁用
    @Override
    public ResponseResult<String> disableUser(String userId, Integer status) {
        if (StringUtils.isBlank(userId)) {
            return ResponseResult.failure(ResponseCode.INTERNAL_ERROR, "请选择用户！", null);
        }
        User users = this.baseMapper.selectById(userId);
        if (users == null) {
            return ResponseResult.failure(ResponseCode.INTERNAL_ERROR, "用户不存在！", null);
        }
        users.setStatus(status);
        if (this.baseMapper.updateById(users) > 0) {
            return ResponseResult.ok("禁用成功！");
        }
        return ResponseResult.failure(ResponseCode.INTERNAL_ERROR, "禁用失败，请稍后再试！", null);
    }

    //删除用户
    @Override
    public ResponseResult<String> deleteUser(String userId) {
        if (StringUtils.isBlank(userId)) {
            return ResponseResult.parameterError(null, "用户ID不能为空！");
        }
        if (applicationContext.getBean(UserService.class).removeById(userId)) {
            return ResponseResult.ok("删除成功！");
        } else {
            return ResponseResult.failure(ResponseCode.INTERNAL_ERROR, "删除失败！", null);
        }
    }

    //获取用户列表z
    @Override
    public ResponseResult<Page<User>> getUserList(Integer pageNum, Integer pageSize, String search, Integer status, Integer userType, String orgId) {
        Page<User> page = new Page<>(pageNum, pageSize);
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        if (StringUtils.isNotBlank(search)) {
            wrapper.and(wrapper1 -> wrapper1
                    .like("username", search)
                    .or()
                    .like("phone", search)
            );
        }
        if (userType != null && userType >= 0) {
            wrapper.eq("user_type", userType);
        }
        if (StringUtils.isNotBlank(orgId)) {
            wrapper.eq("org_id", orgId);
        }
        if (status != null && status >= 0) {
            wrapper.eq("status", status);
        }
        return ResponseResult.ok(this.baseMapper.selectPage(page, wrapper));
    }

    //根据用户id查询用户信息
    @Override
    public User getUserInfoById(String userId) {
        if (StringUtils.isBlank(userId)) {
            return null;
        }
        return this.getById(userId);
    }
}
